from typing import List, Optional
from uuid import UUID

from sqlalchemy import update, delete
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

from model import BidDocument


class BidDocumentCRUD:
    def __init__(self, db: AsyncSession):
        self.db = db

    async def create(self, name: str, file_path: str, tendering_id: UUID,
                     bargaining: bool = False, file_hash: str = "") -> BidDocument:
        """创建一个新的 BidDocument"""
        new_doc = BidDocument(
            name=name,
            file_path=file_path,
            tendering_id=tendering_id,
            bargaining=bargaining,
            file_hash=file_hash
        )
        self.db.add(new_doc)
        await self.db.commit()
        await self.db.refresh(new_doc)
        return new_doc

    async def get_by_id(self, doc_id: UUID) -> Optional[BidDocument]:
        """根据 ID 获取一个 BidDocument"""
        result = await self.db.execute(select(BidDocument).where(BidDocument.id == doc_id))
        return result.scalar_one_or_none()

    async def get_all(self, skip: int = 0, limit: int = 100) -> List[BidDocument]:
        """获取所有 BidDocument（分页）"""
        result = await self.db.execute(select(BidDocument).offset(skip).limit(limit))
        return list(result.scalars().all())

    async def get_by_tender_id(self, tender_id: UUID) -> List[BidDocument]:
        """根据 tender_id 获取所有 BidDocument"""
        result = await self.db.execute(
            select(BidDocument).where(BidDocument.tendering_id == tender_id)
        )
        return list(result.scalars().all())

    async def update(self, doc_id: UUID, name: Optional[str] = None,
                     file_path: Optional[str] = None, bargaining: Optional[bool] = None,
                     file_hash: Optional[str] = None) -> Optional[BidDocument]:
        """更新一个 BidDocument 的字段"""
        stmt = update(BidDocument).where(BidDocument.id == doc_id)
        values = {}
        if name is not None:
            values["name"] = name
        if file_path is not None:
            values["file_path"] = file_path
        if bargaining is not None:
            values["bargaining"] = bargaining
        if file_hash is not None:
            values["file_hash"] = file_hash
        if values:
            stmt = stmt.values(**values).returning(BidDocument)
            result = await self.db.execute(stmt)
            await self.db.commit()
            return result.scalar_one_or_none()
        return None

    async def delete(self, doc_id: UUID) -> bool:
        """删除一个 BidDocument"""
        stmt = delete(BidDocument).where(BidDocument.id == doc_id)
        result = await self.db.execute(stmt)
        await self.db.commit()
        return result.rowcount > 0
